home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 010 / iff / iffcheck.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  6KB  |  216 lines

  1. /*---------------------------------------------------------------------*
  2.  * IFFCheck.C  Print out the structure of an IFF-85 file,      11/19/85
  3.  * checking for structural errors.
  4.  *
  5.  * DO NOT USE THIS AS A SKELETAL PROGRAM FOR AN IFF READER!
  6.  * See ShowILBM.C for a skeletal example.
  7.  *
  8.  * This version for the Commodore-Amiga computer.
  9.  *----------------------------------------------------------------------*/
  10.  
  11. #include "iff.h"
  12.  
  13.  
  14. /* ---------- IFFCheck -------------------------------------------------*/
  15. /* [TBD] More extensive checking could be done on the IDs encountered in the
  16.  * file. Check that the reserved IDs "FOR1".."FOR9", "LIS1".."LIS9", and
  17.  * "CAT1".."CAT9" aren't used. Check that reserved IDs aren't used as Form
  18.  * types. Check that all IDs are made of 4 printable characters (trailing
  19.  * spaces ok). */
  20.  
  21. typedef struct {
  22.     ClientFrame clientFrame;
  23.     int levels;      /* # groups currently nested within.*/
  24.     } Frame;
  25.  
  26. char MsgOkay[] = { "----- (IFF_OKAY) A good IFF file." };
  27. char MsgEndMark[] = {"----- (END_MARK) How did you get this message??" };
  28. char MsgDone[] = { "----- (IFF_DONE) How did you get this message??" };
  29. char MsgDos[] = { "----- (DOS_ERROR) The DOS gave back an error." };
  30. char MsgNot[] = { "----- (NOT_IFF) not an IFF file." };
  31. char MsgNoFile[] = { "----- (NO_FILE) no such file found." };
  32. char MsgClientError[] = {"----- (CLIENT_ERROR) IFF Checker bug."};
  33. char MsgForm[] = { "----- (BAD_FORM) How did you get this message??" };
  34. char MsgShort[] = { "----- (SHORT_CHUNK) How did you get this message??" };
  35. char MsgBad[] = { "----- (BAD_IFF) a mangled IFF file." };
  36.  
  37. /* MUST GET THESE IN RIGHT ORDER!!*/
  38. char *IFFPMessages[-LAST_ERROR+1] = {
  39.     /*IFF_OKAY*/  MsgOkay,
  40.     /*END_MARK*/  MsgEndMark,
  41.     /*IFF_DONE*/  MsgDone,
  42.     /*DOS_ERROR*/ MsgDos,
  43.     /*NOT_IFF*/   MsgNot,
  44.     /*NO_FILE*/   MsgNoFile,
  45.     /*CLIENT_ERROR*/ MsgClientError,
  46.     /*BAD_FORM*/  MsgForm,
  47.     /*SHORT_CHUNK*/  MsgShort,
  48.     /*BAD_IFF*/   MsgBad
  49.     };
  50.  
  51. /* FORWARD REFERENCES */
  52. extern IFFP GetList(/*GroupContext */);
  53. extern IFFP GetForm(/*GroupContext */);
  54. extern IFFP GetProp(/*GroupContext */);
  55. extern IFFP GetCat (/*GroupContext */);
  56.  
  57. void IFFCheck(name)  char *name; {
  58.     IFFP iffp;
  59.     BPTR file = Open(name, MODE_OLDFILE);
  60.     Frame frame;
  61.  
  62.     frame.levels = 0;
  63.     frame.clientFrame.getList = GetList;
  64.     frame.clientFrame.getForm = GetForm;
  65.     frame.clientFrame.getProp = GetProp;
  66.     frame.clientFrame.getCat  = GetCat ;
  67.  
  68.     printf("----- Checking file '%s' -----\n", name);
  69.     if (file == 0)
  70.    iffp = NO_FILE;
  71.     else
  72.    iffp = ReadIFF(file, (ClientFrame *)&frame);
  73.  
  74.     Close(file);
  75.     printf("%s\n", IFFPMessages[-iffp]);
  76.     }
  77.  
  78. main(argc, argv)   int argc;  char **argv; {
  79.     if (argc != 1+1) {
  80.    printf("Usage: 'iffcheck filename'\n");
  81.    exit(0);
  82.    }
  83.     IFFCheck(argv[1]);
  84.     }
  85.  
  86. /* ---------- Put... ---------------------------------------------------*/
  87.  
  88. PutLevels(count)
  89.   int count;
  90.  {
  91.     for ( ;  count > 0;  --count) {
  92.         printf(".");
  93.     }
  94.  }
  95.  
  96. PutID(id)
  97.  ID id;
  98.  {
  99.     printf("%c%c%c%c ", (char)(id>>24)&0x7f, (char)(id>>16)&0x7f,
  100.                              (char)(id>>8)&0x7f, (char)(id&0x7f));
  101. /*    printf("id = %lx", id);  */
  102.   }
  103.  
  104. PutN(n)
  105.     long n;
  106.     {
  107.     printf(" %ld ", n);
  108.     }
  109.  
  110. /* Put something like "...BMHD 14" or "...LIST 14 PLBM". */
  111. PutHdr(context)  GroupContext *context; {
  112.     PutLevels( ((Frame *)context->clientFrame)->levels );
  113.     PutID(context->ckHdr.ckID);
  114.     PutN(context->ckHdr.ckSize);
  115.  
  116.     if (context->subtype != NULL_CHUNK)
  117.    PutID(context->subtype);
  118.  
  119.     printf("\n");
  120.     }
  121.  
  122. /* ---------- AtLeaf ---------------------------------------------------*/
  123.  
  124. /* At Leaf chunk.  That is, a chunk which does NOT contain other chunks.
  125.  * Print "ID size".*/
  126. IFFP AtLeaf(context)  GroupContext *context; {
  127.  
  128.     PutHdr(context);
  129.     /* A typical reader would read the chunk's contents, using the "Frame"
  130.      * for local data, esp. shared property settings (PROP).*/
  131.     /* IFFReadBytes(context, ...buffer, context->ckHdr->ckSize); */
  132.     return(IFF_OKAY);
  133.     }
  134.  
  135. /* ---------- GetList --------------------------------------------------*/
  136. /* Handle a LIST chunk.  Print "LIST size subTypeID".
  137.  * Then dive into it.*/
  138. IFFP GetList(parent)  GroupContext *parent; {
  139.     Frame newFrame;
  140.  
  141.     newFrame = *(Frame *)parent->clientFrame;  /* copy parent's frame*/
  142.     newFrame.levels++;
  143.  
  144.     PutHdr(parent);
  145.  
  146.     return( ReadIList(parent, (ClientFrame *)&newFrame) );
  147.     }
  148.  
  149. /* ---------- GetForm --------------------------------------------------*/
  150. /* Handle a FORM chunk.  Print "FORM size subTypeID".
  151.  * Then dive into it.*/
  152. IFFP GetForm(parent)   GroupContext *parent; {
  153.     /*CompilerBug register*/ IFFP iffp;
  154.     GroupContext new;
  155.     Frame newFrame;
  156.  
  157.     newFrame = *(Frame *)parent->clientFrame;  /* copy parent's frame*/
  158.     newFrame.levels++;
  159.  
  160.     PutHdr(parent);
  161.  
  162.     iffp = OpenRGroup(parent, &new);
  163.     CheckIFFP();
  164.     new.clientFrame = (ClientFrame *)&newFrame;
  165.  
  166.     /* FORM reader for Checker. */
  167.     /* LIST, FORM, PROP, CAT already handled by GetF1ChunkHdr. */
  168.     do {if ( (iffp = GetF1ChunkHdr(&new)) > 0 )
  169.        iffp = AtLeaf(&new);
  170.    } while (iffp >= IFF_OKAY);
  171.  
  172.     CloseRGroup(&new);
  173.     return(iffp == END_MARK ? IFF_OKAY : iffp);
  174.     }
  175.  
  176. /* ---------- GetProp --------------------------------------------------*/
  177. /* Handle a PROP chunk.  Print "PROP size subTypeID".
  178.  * Then dive into it.*/
  179. IFFP GetProp(listContext)  GroupContext *listContext; {
  180.     /*CompilerBug register*/ IFFP iffp;
  181.     GroupContext new;
  182.  
  183.     PutHdr(listContext);
  184.  
  185.     iffp = OpenRGroup(listContext, &new);
  186.     CheckIFFP();
  187.  
  188.     /* PROP reader for Checker. */
  189.     ((Frame *)listContext->clientFrame)->levels++;
  190.  
  191.     do {if ( (iffp = GetPChunkHdr(&new)) > 0 )
  192.        iffp = AtLeaf(&new);
  193.    } while (iffp >= IFF_OKAY);
  194.  
  195.     ((Frame *)listContext->clientFrame)->levels--;
  196.  
  197.     CloseRGroup(&new);
  198.     return(iffp == END_MARK ? IFF_OKAY : iffp);
  199.     }
  200.  
  201. /* ---------- GetCat ---------------------------------------------------*/
  202. /* Handle a CAT chunk.  Print "CAT size subTypeID".
  203.  * Then dive into it.*/
  204. IFFP GetCat(parent)  GroupContext *parent;  {
  205.     IFFP iffp;
  206.  
  207.     ((Frame *)parent->clientFrame)->levels++;
  208.  
  209.     PutHdr(parent);
  210.  
  211.     iffp = ReadICat(parent);
  212.  
  213.     ((Frame *)parent->clientFrame)->levels--;
  214.     return(iffp);
  215.     }
  216.